package bases

import (
	"fmt"
	"log"
	"net/http"
	"runtime"

	"github.com/gin-gonic/gin"
)

// ErrorResponse standardized error response structure
type ErrorResponse struct {
	ErrorCode int         `json:"error_code"`
	ErrorMsg  string      `json:"error_msg"`
	Data      interface{} `json:"data,omitempty"`
	RequestID string      `json:"request_id,omitempty"`
}

// SuccessResponse standardized success response structure  
type SuccessResponse struct {
	ErrorCode int         `json:"error_code"`
	ErrorMsg  string      `json:"error_msg"`
	Data      interface{} `json:"data"`
	RequestID string      `json:"request_id,omitempty"`
}

// SafeError logs error details and returns safe user message
func SafeError(c *gin.Context, err error, userMsg string, statusCode int) {
	// Log detailed error for debugging
	pc, file, line, _ := runtime.Caller(1)
	funcName := runtime.FuncForPC(pc).Name()
	log.Printf("Error in %s [%s:%d]: %v", funcName, file, line, err)
	
	requestID := c.GetString("RequestID")
	
	response := ErrorResponse{
		ErrorCode: 1,
		ErrorMsg:  userMsg,
		Data:      nil,
		RequestID: requestID,
	}
	
	c.JSON(statusCode, response)
}

// SafeSuccess returns standardized success response
func SafeSuccess(c *gin.Context, data interface{}, msg string) {
	requestID := c.GetString("RequestID")
	
	response := SuccessResponse{
		ErrorCode: 0,
		ErrorMsg:  msg,
		Data:      data,
		RequestID: requestID,
	}
	
	c.JSON(http.StatusOK, response)
}

// DatabaseError handles database-related errors
func DatabaseError(c *gin.Context, err error) {
	SafeError(c, err, "Database operation failed", http.StatusInternalServerError)
}

// ValidationError handles input validation errors
func ValidationError(c *gin.Context, err error) {
	SafeError(c, err, "Invalid input data", http.StatusBadRequest)
}

// NotFoundError handles resource not found errors
func NotFoundError(c *gin.Context, resource string) {
	msg := fmt.Sprintf("%s not found", resource)
	SafeError(c, fmt.Errorf("resource not found: %s", resource), msg, http.StatusNotFound)
}

// UnauthorizedError handles authentication errors
func UnauthorizedError(c *gin.Context) {
	SafeError(c, fmt.Errorf("unauthorized access"), "Authentication required", http.StatusUnauthorized)
}

// InternalError handles unexpected internal errors
func InternalError(c *gin.Context, err error) {
	SafeError(c, err, "Internal server error", http.StatusInternalServerError)
}